/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#include "World.h"
#include "InputSystem.h"
#include "Application.h"

namespace Fish3D
{
	World::World(void)
		: _win(0),_root(0),_sceneMgr(0),_camera(0),_cameraController(0),
		_waterManager(0),_skyManager(0),_fishManager(0),_avatar(0),_rightMouseDown(false)
	{
	}

	World::~World(void)
	{
	}

	void World::init(Ogre::RenderWindow* win)
	{
		_win=win;
		_root=Ogre::Root::getSingletonPtr();
		_sceneMgr = _root->createSceneManager(Ogre::ST_EXTERIOR_CLOSE);

		_camera=_sceneMgr->createCamera(CameraNames::Normal);
		

		_cameraController=new CameraController(_camera);

		setupViewport();
		
		setupScene();
		
		setupGUI();
		setupInputListener();

		//setupAvatar();
	}

	void World::setupAvatar()
	{
		_avatar=new Avatar(_camera);
		_avatar->setPostion(700,0,700);
	}

	void World::setupGUI()
	{
		//GUISystem::getSingleton().setupGUI(TEST_WORLD_2_GUI,_win,_sceneMgr);	
	}

	void World::setupInputListener()
	{
		InputSystem::getSingleton().addKeyListener(this,"KeyListener");
		InputSystem::getSingleton().addMouseListener(this,"MouseListener");
	}

	void World::setupScene()
	{
		_sceneMgr->setWorldGeometry("OceneTerrain.cfg");
		_skyManager=new SkyEffectManager(_sceneMgr);
		_waterManager=new WaterEffectManager(_sceneMgr);
		_fishManager=new FishManager(_sceneMgr);
	}

	void World::setupViewport()
    {
        // Create one viewport, entire window
		Ogre::Viewport* vp = _win->addViewport(_camera);
		vp->setBackgroundColour(Ogre::ColourValue(0,0,0));

        // Alter the camera aspect ratio to match the viewport
		_camera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
    }

	void World::update(float deltaT)
	{
		//First update camera
		if(_cameraController){
			_cameraController->update(deltaT);
		}

		// Update Sky effect
		if(_skyManager){
			_skyManager->update(deltaT);
		}

		// Update Water effect
		if(_waterManager){
			_waterManager->update(deltaT);
		}

		if(_fishManager){
			_fishManager->update(deltaT);

		}

		if(_avatar){
			_avatar->update(deltaT);
		}
	}

	bool World::keyPressed(const OIS::KeyEvent &e)
	{
		switch(e.key){
			case OIS::KC_ESCAPE:
				Application::getSingleton().shutdown();
				return false;
		}
		
		if(_skyManager){
			_skyManager->injectKeyDown(e);
		}

		/*
		CEGUI::System *sys = CEGUI::System::getSingletonPtr();
		sys->injectKeyDown(e.key);
		sys->injectChar(e.text);
		*/
		
		if(_avatar){
			_avatar->injectKeyDown(e);
		}
		return true;
	}

	bool World::keyReleased( const OIS::KeyEvent &e)
	{
		

		/*
		if(CEGUI::System::getSingleton().injectKeyUp(e.key)){
			return true;
		}
		*/
		if(_avatar){
			_avatar->injectKeyUp(e);
		}
		return true;
	}

	bool World::mouseMoved( const OIS::MouseEvent &e)
	{
		

		/*
		if(CEGUI::System::getSingleton().injectMouseMove(e.state.X.rel, e.state.Y.rel)){
			return true;
		}
		*/

		if(_avatar){
			_avatar->injectMouseMove(e);
		}
		return true;
	}

	bool World::mousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id)
	{
		/*
		if(CEGUI::System::getSingleton().injectMouseButtonDown(Utility::convertButton(id))){
			return true;
		}
		*/
		if(_avatar){
			_avatar->injectMouseDown(e,id);
		}
		return true;
	}
	
	bool World::mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id )
	{
		

		/*
		if(CEGUI::System::getSingleton().injectMouseButtonUp(Utility::convertButton(id))){
			return true;
		}
		*/
		
		_rightMouseDown=false;
		return true;
	}
}
